/**
 * @file voice_msg_list.c
 *
 */

/*********************
*      INCLUDES
*********************/
#include "lv_watch.h"

#if USE_LV_WATCH_VOICE_MSG != 0

/*********************
*      DEFINES
*********************/

/**********************
*      TYPEDEFS
**********************/

/**********************
*  STATIC PROTOTYPES
**********************/
static lv_res_t voice_msg_scrl_signal(lv_obj_t * scrl, lv_signal_t sign, void * param);
static void voice_msg_play_voice(lv_obj_t * len_label, lv_voice_msg_list_ext_t * list_ext);
static void voice_msg_list_voicebtn_event_cb(lv_obj_t * img, lv_event_t e);
static void voice_msg_small_photo_event_cb(lv_obj_t * img, lv_event_t e);

/**********************
*  STATIC VARIABLES
**********************/
static lv_signal_cb_t ancient_scrl_signal;

/**********************
 *      MACROS
 **********************/

/**********************
 *   GLOBAL FUNCTIONS
***********************/
lv_obj_t * voice_msg_list_create(lv_obj_t * par, uint16_t width, uint16_t height)
{
    lv_obj_t * list = lv_page_create(par, NULL);
    lv_voice_msg_list_ext_t * ext = lv_obj_allocate_ext_attr(list, sizeof(lv_voice_msg_list_ext_t));
    lv_obj_set_size(list, width, height);
    lv_page_set_scrollbar_mode(list, LV_SCROLLBAR_MODE_OFF);
    lv_obj_set_style_local_bg_opa(list,
                                  LV_PAGE_PART_BG,
                                  LV_STATE_DEFAULT,
                                  LV_OPA_0);
    lv_obj_set_style_local_border_opa(list,
                                      LV_PAGE_PART_BG,
                                      LV_STATE_DEFAULT,
                                      LV_OPA_0);
    lv_obj_set_style_local_outline_width(list,
                                         LV_PAGE_PART_BG,
                                         LV_STATE_DEFAULT,
                                         0);
    lv_obj_set_style_local_pad_bottom(list,
                                      LV_PAGE_PART_SCROLLABLE,
                                      LV_STATE_DEFAULT,
                                      4);
    lv_obj_set_style_local_pad_top(list,
                                   LV_PAGE_PART_SCROLLABLE,
                                   LV_STATE_DEFAULT,
                                   2);
    lv_obj_set_style_local_pad_inner(list,
                                     LV_PAGE_PART_SCROLLABLE,
                                     LV_STATE_DEFAULT,
                                     8);
    lv_obj_set_style_local_bg_color(list,
                                    LV_PAGE_PART_SCROLLBAR,
                                    LV_STATE_DEFAULT,
                                    LV_COLOR_MAKE(16, 112, 194));
    lv_obj_set_style_local_pad_inner(list,
                                     LV_PAGE_PART_SCROLLBAR,
                                     LV_STATE_DEFAULT,
                                     LV_DPI / 20);
    lv_obj_set_style_local_pad_left(list,
                                    LV_PAGE_PART_SCROLLBAR,
                                    LV_STATE_DEFAULT,
                                    0);
    lv_obj_set_style_local_pad_right(list,
                                     LV_PAGE_PART_SCROLLBAR,
                                     LV_STATE_DEFAULT,
                                     0);
    lv_obj_set_style_local_radius(list,
                                  LV_PAGE_PART_SCROLLBAR,
                                  LV_STATE_DEFAULT,
                                  0);

    memset(&(ext->voice_playing_anim), 0, sizeof(lv_anim_t));
    ext->pressing = false;

    lv_style_init(&ext->style_label_time);
    lv_style_copy(&ext->style_label_time, &lv_watch_font20);
    lv_style_set_text_color(&ext->style_label_time, LV_STATE_DEFAULT, LV_COLOR_MAKE(20, 187, 242));

    lv_style_init(&ext->style_text);
    lv_style_copy(&ext->style_text, &lv_style_pretty);
    lv_style_set_bg_color(&ext->style_text, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xFF, 0xE1, 0xE1));
    lv_style_set_border_width(&ext->style_text, LV_STATE_DEFAULT, 0);
    lv_style_set_shadow_width(&ext->style_text, LV_STATE_DEFAULT, 0);

    lv_style_init(&ext->style_label_len_other);
    lv_style_copy(&ext->style_label_len_other, &lv_watch_font20);
    lv_style_set_text_color(&ext->style_label_len_other, LV_STATE_DEFAULT, LV_COLOR_MAKE(202, 134, 255));

    lv_style_init(&ext->style_label_len_ui);
    lv_style_copy(&ext->style_label_len_ui, &lv_watch_font20);
    lv_style_set_text_color(&ext->style_label_len_ui, LV_STATE_DEFAULT, LV_COLOR_MAKE(108, 189, 5));

    lv_style_init(&ext->style_cont);
    lv_style_set_pad_top(&ext->style_cont, LV_STATE_DEFAULT, 8);
    lv_style_set_pad_bottom(&ext->style_cont, LV_STATE_DEFAULT, 8);
    lv_style_set_pad_left(&ext->style_cont, LV_STATE_DEFAULT, 8);
    lv_style_set_pad_right(&ext->style_cont, LV_STATE_DEFAULT, 8);

    lv_page_set_scrl_layout(list, LV_LAYOUT_OFF);
    lv_page_set_scrollable_fit2(list, LV_FIT_NONE, LV_FIT_TIGHT);
    lv_obj_t * scrl = lv_page_get_scrl(list);
    ancient_scrl_signal = lv_obj_get_signal_cb(scrl);
    lv_obj_set_signal_cb(scrl, voice_msg_scrl_signal);

    lv_watch_obj_add_element(list);
    lv_watch_obj_add_element(scrl);

    return list;
}

lv_obj_t * voice_msg_list_add(lv_obj_t * list, voice_msg_desc_t * msg_desc)
{
    printf("%s: msg type %d\n", __FUNCTION__, msg_desc->type);

    lv_voice_msg_list_ext_t * ext = lv_obj_get_ext_attr(list);
    lv_obj_t * scrl = lv_page_get_scrl(list);
    lv_obj_t * last_obj = lv_obj_get_child(scrl, NULL);
    lv_coord_t obj_h = lv_obj_get_style_pad_top(scrl, LV_STATE_DEFAULT);
    if(last_obj) {
        if(VOICE_MSG_TYPE_UNREAD_FLAG == VOICE_MSG_GET_MSG_TYPE(voice_msg_get_user_num(last_obj))) {
            /*get voice obj*/
            last_obj = lv_obj_get_child(scrl, last_obj);
        }
        obj_h = lv_obj_get_y(last_obj)
            + lv_obj_get_height(last_obj)
            + lv_obj_get_style_pad_inner(scrl, LV_STATE_DEFAULT);
    }
    uint32_t free_num = 0;
    VOICE_MSG_SET_MSG_TYPE(free_num, msg_desc->type);
    if(1 == msg_desc->direction) {
        VOICE_MSG_SET_MSG_FROM_SERVICE(free_num);
    }
    lv_obj_t * obj;
    if(msg_desc->type == VOICE_MSG_TYPE_TIME) { /*time*/
        obj = lv_label_create(list, NULL);
        if(LV_BIDI_DIR_RTL == lv_obj_get_base_dir(obj)) {
            lv_obj_set_base_dir(obj, LV_BIDI_DIR_LTR);
        }
        lv_label_set_text(obj, msg_desc->time_str);
        lv_obj_add_style(obj, LV_LABEL_PART_MAIN, &ext->style_label_time);
        lv_obj_align(obj, scrl, LV_ALIGN_IN_TOP_MID, 0, obj_h);
    } else if(msg_desc->type == VOICE_MSG_TYPE_NAME) {/*name*/
        obj = lv_label_create(list, NULL);
        lv_label_set_text(obj, msg_desc->name_str);
        lv_obj_add_style(obj, LV_LABEL_PART_MAIN, &lv_watch_font20_gray);
        if(msg_desc->direction == 1) {
            lv_obj_align(obj, scrl, LV_ALIGN_IN_TOP_LEFT, 10, obj_h);
        } else {
            lv_obj_align(obj, scrl, LV_ALIGN_IN_TOP_RIGHT, -10, obj_h);
        }
    } else if(msg_desc->type == VOICE_MSG_TYPE_TEXT) { /*text*/
        obj = lv_cont_create(list, NULL);
        lv_obj_add_style(obj, LV_CONT_PART_MAIN, &ext->style_cont);
        lv_cont_set_fit(obj, true);
        lv_obj_t * chat_label = lv_label_create(obj, NULL);
        lv_obj_add_style(chat_label, LV_LABEL_PART_MAIN, &lv_watch_font20_black);
        char * text = NULL;
        if(0 == msg_desc->size) {
            /*file path string*/
            text = voice_msg_read_file_data(msg_desc->data, VOICE_MSG_TYPE_TEXT, NULL);
            printf("%s: read text %s\n", __FUNCTION__, text);
        } else {
            /*text string*/
            text = msg_desc->data;
        }
        lv_label_set_text(chat_label, text);
        lv_coord_t width = _lv_txt_get_width(text,
                                             strlen(text),
                                             LV_THEME_WATCH_NIGHT_FONT_SMALL,
                                             0,
                                             LV_TXT_FLAG_NONE);
        if(width > LV_HOR_RES * 3 / 4) {
            lv_label_set_long_mode(chat_label, LV_LABEL_LONG_BREAK);
            lv_obj_set_width(chat_label, LV_HOR_RES * 3 / 4);
        }
        if(msg_desc->direction == 1) {
            obj_h += lv_obj_get_style_pad_top(obj, LV_STATE_DEFAULT);
            lv_obj_align(obj, scrl, LV_ALIGN_IN_TOP_LEFT,
                         10 + lv_obj_get_style_pad_left(obj, LV_STATE_DEFAULT),
                         obj_h);
            lv_obj_add_style(obj, LV_CONT_PART_MAIN, &ext->style_text);
        }
        lv_obj_set_click(obj, false);
        if(0 == msg_desc->size) {
            lv_mem_free(text);
        }
    } else if(msg_desc->type == VOICE_MSG_TYPE_VOICE) { /*voice*/
        obj = lv_img_create(list, NULL);
        lv_obj_t * playing_img = lv_img_create(obj, NULL);
        lv_obj_t * len_label = lv_label_create(obj, NULL);
        uint32_t duration = 0;
        if(0 == msg_desc->size) {
            /*file path string*/
            if(LV_FS_RES_OK != Hal_File_Get_AudioDurationTime(
                   (const char *)msg_desc->data, &duration)) {
                printf("%s: read voice file %s error\n", __FUNCTION__, (char *)msg_desc->data);
            } else {
                duration = (duration + 999) / 1000;
            }
        } else {
            /*data buffer*/
            printf("%s: data buffer, voice msg size %d\n", __FUNCTION__, msg_desc->size);
            if(VOICE_MSG_AMR_HEAD_SIZE < msg_desc->size) {
                duration
                    = (msg_desc->size - VOICE_MSG_AMR_HEAD_SIZE + HAL_AMR_BUFSIZE_PER_SECOND - 1)
                    / HAL_AMR_BUFSIZE_PER_SECOND;
            }
        }
        if(0 == duration) {
            /*invalid voice*/
            lv_img_set_src(playing_img, ICON_VOICE_DAMAGE);
            lv_label_set_text(len_label, "");
        } else {
            char len_str[4] = {0};
            snprintf(len_str, 4, "%dS", duration);
            lv_label_set_text(len_label, len_str);
        }
        if(msg_desc->direction == 1) {
            lv_obj_add_style(len_label, LV_LABEL_PART_MAIN, &ext->style_label_len_other);
            lv_img_set_src(obj, ICON_VOICE_BUBBLE);
            lv_obj_align(obj, scrl, LV_ALIGN_IN_TOP_LEFT, 10, obj_h);
            if(0 < duration) {
                lv_img_set_src(playing_img, ICON_PLAYING3);
            }
            lv_obj_align(playing_img, obj, LV_ALIGN_IN_RIGHT_MID, -10, 0);
            lv_obj_align(len_label, playing_img, LV_ALIGN_OUT_LEFT_MID, -30, 0);
            if(msg_desc->have_read == 0) {
                lv_obj_t * read_img = lv_img_create(list, NULL);
                lv_img_set_src(read_img, ICON_REMIND);
                lv_obj_align(read_img, obj, LV_ALIGN_OUT_RIGHT_MID, 5, 0);
                uint32_t read_img_free_num = 0;
                VOICE_MSG_SET_VOICE_INDEX(read_img_free_num, msg_desc->voice_index);
                VOICE_MSG_SET_MSG_TYPE(read_img_free_num, VOICE_MSG_TYPE_UNREAD_FLAG);
                voice_msg_set_user_num(read_img, read_img_free_num);
                VOICE_MSG_SET_UNREAD_FLAG(free_num);
            }
        } else {
            lv_obj_add_style(len_label, LV_LABEL_PART_MAIN, &ext->style_label_len_ui);
            lv_img_set_src(obj, ICON_MY_VOICE_BUBBLE);
            lv_obj_align(obj, scrl, LV_ALIGN_IN_TOP_RIGHT, -10, obj_h);
            if(0 < duration) {
                lv_img_set_src(playing_img, ICON_MY_PLAYING3);
            }
            lv_obj_align(playing_img, obj, LV_ALIGN_IN_LEFT_MID, 10, 0);
            lv_obj_align(len_label, playing_img, LV_ALIGN_OUT_RIGHT_MID, 30, 0);
        }
        if(0 < duration) {
            voice_msg_set_user_num(len_label, msg_desc->size);
            voice_msg_set_user_ptr(len_label, msg_desc->data);
        } else {
            /*invalid voice*/
            voice_msg_set_user_num(len_label, 0);
            voice_msg_set_user_ptr(len_label, NULL);
            if(msg_desc->data) {
                lv_mem_free(msg_desc->data);
            }
        }
        lv_obj_set_click(obj, true);
        lv_page_glue_obj(obj, true);
        lv_obj_set_event_cb(obj, voice_msg_list_voicebtn_event_cb);
        lv_obj_set_adv_hittest(obj, false);
        lv_watch_obj_add_element(obj);
    } else if((msg_desc->type == VOICE_MSG_TYPE_EXPRESSION)
              || (msg_desc->type == VOICE_MSG_TYPE_PHOTO)) { /*expression or photo*/
        obj = lv_img_create(list, NULL);
        if(0 == msg_desc->size) {
            /*data file*/
            lv_img_set_src(obj, msg_desc->data);
        } else {
            /*data buffer*/
            lv_img_dsc_t * dsc = (lv_img_dsc_t *)lv_mem_alloc(sizeof(lv_img_dsc_t));
            memset(dsc, 0, sizeof(lv_img_dsc_t));
            lv_img_cache_invalidate_src(dsc);

            if(msg_desc->type == VOICE_MSG_TYPE_EXPRESSION) {
                dsc->header.w = VOICE_MSG_EXPRESSION_WIDTH;
                dsc->header.h = VOICE_MSG_EXPRESSION_HEIGHT;
                dsc->header.cf = LV_IMG_CF_RAW_ALPHA;
            } else {
                dsc->header.w = VOICE_MSG_PHOTO_WIDTH;
                dsc->header.h = VOICE_MSG_PHOTO_HEIGHT;
                dsc->header.cf = LV_IMG_CF_RAW;
                lv_obj_set_click(obj, true);
                lv_page_glue_obj(obj, true);
                lv_obj_set_event_cb(obj, voice_msg_small_photo_event_cb);
                lv_obj_set_adv_hittest(obj, false);
            }
            dsc->data_size = msg_desc->size;
            dsc->data = (uint8_t *)msg_desc->data;
            lv_img_set_src(obj, dsc);
        }
        if(msg_desc->type == VOICE_MSG_TYPE_EXPRESSION) {
            lv_obj_set_click(obj, false);
        } else {
            lv_obj_set_click(obj, true);
            lv_page_glue_obj(obj, true);
            lv_obj_set_event_cb(obj, voice_msg_small_photo_event_cb);
            lv_obj_set_adv_hittest(obj, false);
        }
        if(msg_desc->direction == 1) {
            lv_obj_align(obj, scrl, LV_ALIGN_IN_TOP_LEFT, 10, obj_h);
        } else {
            lv_obj_align(obj, scrl, LV_ALIGN_IN_TOP_RIGHT, -10, obj_h);
        }
        lv_watch_obj_add_element(obj);
    } else if(msg_desc->type == VOICE_MSG_TYPE_EMO_AND_TOUCH) { /*send emo and touch spk*/
        lv_voice_msg_chat_ext_t * chat_ext = voice_msg_get_ext(ACT_ID_VOICE_MSG_CHAT);
        if(NULL == chat_ext) return NULL;

        obj = lv_cont_create(list, NULL);
        lv_obj_add_style(obj, LV_CONT_PART_MAIN, &lv_watch_style_transp);

        if(chat_ext->img_emo) {
            lv_obj_set_parent(chat_ext->img_emo, obj);
        } else {
            chat_ext->img_emo = lv_img_create(obj, NULL);
            lv_img_set_src(chat_ext->img_emo, ICON_SEND_EMO);
            lv_obj_set_click(chat_ext->img_emo, true);
            lv_obj_set_event_cb(chat_ext->img_emo, voice_msg_send_emo_event_cb);
            lv_obj_set_adv_hittest(chat_ext->img_emo, false);
            lv_watch_obj_add_element(chat_ext->img_emo);
        }

        if(chat_ext->img_touch) {
            // the parent of img touch has been changed when to add new msg into chat
            lv_obj_set_parent(chat_ext->img_touch, obj);
            printf("%s: img touch is present\n", __FUNCTION__);
        } else {
            chat_ext->img_touch = lv_img_create(obj, NULL);
            lv_img_set_src(chat_ext->img_touch, ICON_TOUCH_SPK);
            lv_obj_set_click(chat_ext->img_touch, true);
            lv_obj_set_event_cb(chat_ext->img_touch, voice_msg_touch_spk_event_cb);
            lv_obj_set_adv_hittest(chat_ext->img_touch, false);
            lv_watch_obj_add_element(chat_ext->img_touch);
        }

        lv_obj_set_size(obj, lv_obj_get_width(scrl), lv_obj_get_height(chat_ext->img_touch));
        lv_obj_align(obj, scrl, LV_ALIGN_IN_TOP_MID, 0, obj_h);

        if(LV_BIDI_DIR_RTL == lv_obj_get_base_dir(obj)) {
            lv_obj_align(chat_ext->img_emo, obj, LV_ALIGN_IN_RIGHT_MID, -10, 0);
            lv_obj_align(chat_ext->img_touch, obj, LV_ALIGN_IN_LEFT_MID, 10, 0);
        } else {
            lv_obj_align(chat_ext->img_touch, obj, LV_ALIGN_IN_RIGHT_MID, -10, 0);
            lv_obj_align(chat_ext->img_emo, obj, LV_ALIGN_IN_LEFT_MID, 10, 0);
        }
    } else {
        printf("Wrong voice msg type!\n");
        return NULL;
    }

    voice_msg_set_user_num(obj, free_num);

    return obj;
}
/**********************
 *   STATIC FUNCTIONS
 **********************/
static lv_res_t voice_msg_scrl_signal(lv_obj_t * scrl, lv_signal_t sign, void * param)
{
    lv_res_t res;

    /* Include the ancient signal function */
    res = ancient_scrl_signal(scrl, sign, param);
    if(res != LV_RES_OK) return res;

    if(LV_SIGNAL_COORD_CHG == sign) {
        lv_obj_t * list = lv_obj_get_parent(scrl);
        lv_voice_msg_list_ext_t * list_ext = (lv_voice_msg_list_ext_t *)lv_obj_get_ext_attr(list);
        if(true == list_ext->pressing) {
            list_ext->pressing = false;
        }
    }

    return LV_RES_OK;
}

static void voice_msg_list_voiceplaying_anim(lv_anim_t * a)
{
    lv_obj_t * play_img = (lv_obj_t *)a->var;
    lv_obj_t * bubble_img = lv_obj_get_parent(play_img);
    uint8_t direction = VOICE_MSG_IS_MSG_FROM_SERVICE(voice_msg_get_user_num(bubble_img));
    uint32_t anim_step = voice_msg_get_user_num(play_img);
    if(3 == anim_step) {
        if(1 == direction) {
            lv_img_set_src(play_img, ICON_PLAYING1);
        } else {
            lv_img_set_src(play_img, ICON_MY_PLAYING1);
        }
        voice_msg_set_user_num(play_img, 1);
    } else if(2 == anim_step) {
        if(1 == direction) {
            lv_img_set_src(play_img, ICON_PLAYING3);
        } else {
            lv_img_set_src(play_img, ICON_MY_PLAYING3);
        }
        voice_msg_set_user_num(play_img, 3);
    } else if(1 == anim_step) {
        if(1 == direction) {
            lv_img_set_src(play_img, ICON_PLAYING2);
        } else {
            lv_img_set_src(play_img, ICON_MY_PLAYING2);
        }
        voice_msg_set_user_num(play_img, 2);
    }
}

static void voice_msg_create_voice_anim(lv_obj_t * play_img, lv_voice_msg_list_ext_t * list_ext)
{
    voice_msg_set_user_num(play_img, 3);

    lv_anim_init(&list_ext->voice_playing_anim);
    lv_anim_set_var(&list_ext->voice_playing_anim, play_img);
    lv_anim_set_start_cb(&list_ext->voice_playing_anim, (lv_anim_ready_cb_t)voice_msg_list_voiceplaying_anim);
    lv_anim_set_repeat_count(&list_ext->voice_playing_anim, LV_ANIM_REPEAT_INFINITE);
    lv_anim_set_time(&list_ext->voice_playing_anim, 400);
    lv_anim_start(&list_ext->voice_playing_anim);
}

static void voice_msg_inform_voice_read(uint8_t index)
{
    lv_voice_msg_chat_ext_t * ext = voice_msg_get_ext(ACT_ID_VOICE_MSG_CHAT);
    if(NULL == ext) return;
    app_adaptor_voice_msg_chat_id_t * id = (app_adaptor_voice_msg_chat_id_t *)lv_mem_alloc(sizeof(app_adaptor_voice_msg_chat_id_t));
    id->name = NULL;
    id->number = NULL;
    voice_msg_fill_chat_id(id, ext->cur_contact);
    app_adaptor_voice_msg_read_voice_req(id, index);
}

static void voice_msg_voice_over_task_cb(void * para)
{
    printf("%s: for chat list\n", __FUNCTION__);
    (void)para;
    Hal_Audio_Manage_End_Ind(AUDIO_CTRL_PRIORITY_5);

    lv_voice_msg_chat_ext_t * chat_ext = voice_msg_get_ext(ACT_ID_VOICE_MSG_CHAT);
    if(NULL == chat_ext)  {
        printf("%s: chat_ext NULL\n", __FUNCTION__);
        return;
    }
    lv_voice_msg_list_ext_t * list_ext = lv_obj_get_ext_attr(chat_ext->list);
    if(NULL == list_ext) return;
    if(NULL == list_ext->voice_playing_anim.var) {
        printf("%s: anim var NULL\n", __FUNCTION__);
        return;
    }

    lv_anim_del(list_ext->voice_playing_anim.var, list_ext->voice_playing_anim.exec_cb);
    lv_obj_t * voice_img = lv_obj_get_parent(list_ext->voice_playing_anim.var);
    uint8_t direction = VOICE_MSG_IS_MSG_FROM_SERVICE(voice_msg_get_user_num(voice_img));
    if(direction) {
        lv_img_set_src(list_ext->voice_playing_anim.var, ICON_PLAYING3);
    } else {
        lv_img_set_src(list_ext->voice_playing_anim.var, ICON_MY_PLAYING3);
    }
    list_ext->voice_playing_anim.var = NULL;

    if(1 != direction) {
        /*the voice is from the local, not go on to play the next unread voice from server*/
        return;
    }

    lv_obj_t * scrl = lv_obj_get_parent(voice_img);
    lv_obj_t * next_voice_img = lv_obj_get_child_back(scrl, voice_img);
    if(NULL == next_voice_img) return;
    uint32_t user_num = voice_msg_get_user_num(next_voice_img);
    if(VOICE_MSG_IS_UNREAD_FLAG(user_num)) {
        lv_obj_t * next_play_img = lv_obj_get_child_back(next_voice_img, NULL);
        lv_obj_t * next_len_label = lv_obj_get_child_back(next_voice_img, next_play_img);
        if(NULL == voice_msg_get_user_ptr(next_len_label)) {
            return;
        }
        voice_msg_set_user_num(next_voice_img, VOICE_MSG_CLEAR_UNREAD_FLAG(user_num));
        lv_obj_t * next_read_img = lv_obj_get_child_back(scrl, next_voice_img);
        /*go on playing voice of next message for the same contact*/
        voice_msg_create_voice_anim(next_play_img, list_ext);
        voice_msg_play_voice(next_len_label, list_ext);
        uint8_t index = VOICE_MSG_GET_VOICE_INDEX(voice_msg_get_user_num(next_read_img));
        lv_obj_del(next_read_img);
        voice_msg_inform_voice_read(index);
    }
}

static void voice_msg_voice_over_cb(void * para)
{
    lv_async_call(voice_msg_voice_over_task_cb, para);
}

static void voice_msg_play_voice(lv_obj_t * len_label, lv_voice_msg_list_ext_t * list_ext)
{
    void * buffer = (uint32_t *)(voice_msg_get_user_ptr(len_label));
    uint32_t len = voice_msg_get_user_num(len_label);
    Hal_Audio_Manage_Start_Req(AUDIO_CTRL_PRIORITY_5,voice_msg_audio_ctrl_callback);
    Voice_Msg_Play_Onetime(buffer,
                           len,
                           query_current_volume(),
                           voice_msg_voice_over_cb,
                           list_ext);
}

static void voice_msg_list_voicebtn_event_cb(lv_obj_t * img, lv_event_t e)
{
    lv_obj_t * scrl = lv_obj_get_parent(img);
    lv_obj_t * list = lv_obj_get_parent(scrl);
    lv_voice_msg_list_ext_t * list_ext = (lv_voice_msg_list_ext_t *)lv_obj_get_ext_attr(list);
    if(NULL == list_ext) return;

    if(LV_EVENT_PRESSED == e) {
        list_ext->pressing = true;
    } else if((true == list_ext->pressing) && (LV_EVENT_CLICKED == e)) {
        list_ext->pressing = false;
        lv_obj_t * play_img = lv_obj_get_child_back(img, NULL);
        lv_obj_t * len_label = lv_obj_get_child_back(img, play_img);
        void * voice_buf = voice_msg_get_user_ptr(len_label);
        printf("%s: voice_buf %p, anim var %p\n",
               __FUNCTION__, voice_buf, list_ext->voice_playing_anim.var);
        if(list_ext->voice_playing_anim.var) {
            lv_obj_t * old_img = lv_obj_get_parent(list_ext->voice_playing_anim.var);
            lv_obj_t * old_len_label = lv_obj_get_child_back(old_img, list_ext->voice_playing_anim.var);
            uint32_t voice_len = voice_msg_get_user_num(old_len_label);
            printf("%s: stop the current voice, size %d\n", __FUNCTION__, voice_len);
            voice_msg_play_end(voice_len);
            Hal_Audio_Manage_End_Ind(AUDIO_CTRL_PRIORITY_5);
            if(list_ext->voice_playing_anim.var != play_img) {
                lv_anim_del(list_ext->voice_playing_anim.var, NULL);
                if(VOICE_MSG_IS_MSG_FROM_SERVICE(voice_msg_get_user_num(old_img))) {
                    lv_img_set_src(list_ext->voice_playing_anim.var, ICON_PLAYING3);
                } else {
                    lv_img_set_src(list_ext->voice_playing_anim.var, ICON_MY_PLAYING3);
                }
                list_ext->voice_playing_anim.var = NULL;
                if(voice_buf) {
                    voice_msg_create_voice_anim(play_img, list_ext);
                }
            }
            if(voice_buf) {
                voice_msg_play_voice(len_label, list_ext);
            }
        } else if(voice_buf) {
            voice_msg_create_voice_anim(play_img, list_ext);
            voice_msg_play_voice(len_label, list_ext);
        }

        if(voice_buf) {
            uint32_t user_num = voice_msg_get_user_num(img);
            if(VOICE_MSG_IS_UNREAD_FLAG(user_num)) {
                voice_msg_set_user_num(img, VOICE_MSG_CLEAR_UNREAD_FLAG(user_num));
                lv_obj_t * read_img = lv_obj_get_child_back(scrl, img);
                uint8_t index = VOICE_MSG_GET_VOICE_INDEX(voice_msg_get_user_num(read_img));
                lv_obj_del(read_img);
                /*inform sdk that the message has been read*/
                voice_msg_inform_voice_read(index);
            }
        }
    }
}

static void voice_msg_small_photo_event_cb(lv_obj_t * img, lv_event_t e)
{
    lv_obj_t * scrl = lv_obj_get_parent(img);
    lv_obj_t * list = lv_obj_get_parent(scrl);
    lv_voice_msg_list_ext_t * list_ext = (lv_voice_msg_list_ext_t *)lv_obj_get_ext_attr(list);
    if(NULL == list_ext) return;

    if(LV_EVENT_PRESSED == e) {
        list_ext->pressing = true;
    } else if((true == list_ext->pressing) && (LV_EVENT_CLICKED == e)) {
        list_ext->pressing = false;
        if(list_ext->voice_playing_anim.var) {
            lv_obj_t * old_img = lv_obj_get_parent(list_ext->voice_playing_anim.var);
            lv_obj_t * old_len_label = lv_obj_get_child_back(old_img, list_ext->voice_playing_anim.var);
            uint32_t voice_len = voice_msg_get_user_num(old_len_label);
            printf("%s: stop the current voice, size %d\n", __FUNCTION__, voice_len);
            voice_msg_play_end(voice_len);
            Hal_Audio_Manage_End_Ind(AUDIO_CTRL_PRIORITY_5);
            lv_anim_del(list_ext->voice_playing_anim.var, NULL);
            if(VOICE_MSG_IS_MSG_FROM_SERVICE(voice_msg_get_user_num(old_img))) {
                lv_img_set_src(list_ext->voice_playing_anim.var, ICON_PLAYING3);
            } else {
                lv_img_set_src(list_ext->voice_playing_anim.var, ICON_MY_PLAYING3);
            }
            list_ext->voice_playing_anim.var = NULL;
        }

        voice_msg_enlarge_photo((void *)lv_img_get_src(img));
    }
}

#endif /*USE_LV_WATCH_VOICE_MSG*/
